/**
 * 主窗口
 */

import * as remote from "@electron/remote/main"
import { ipcMain, BrowserWindow, type BrowserWindowConstructorOptions, dialog } from "electron"
import { LocalLogger } from "./AppLogger"
import { AppConfig } from "./AppConfig"
import IpcDict from "../tool/ipc-dict"
import PKG from "../../package.json";

import NodePath, {join} from "path"

export default class WinMain {
  // 打印日志
  private static printf(...params: any[]) {
    LocalLogger.Index.log(...params)
  }

  /** 窗口实例 */
  private static winInst: BrowserWindow | null = null
  private static printWin: BrowserWindow | null = null
  /** 窗口配置 */
  private static winOption: BrowserWindowConstructorOptions = {
    icon: AppConfig.getAppLogo(), // 图标
    title: AppConfig.getAppTitle(), // 如果由 loadURL() 加载的 HTML 文件中含有标签 <title>，此属性将被忽略
    minWidth: 1200,
    minHeight: 768,
    show: false, // 是否在创建时显示, 默认值为 true
    frame: true, // 是否有边框
    center: true, // 是否在屏幕居中
    hasShadow: false, // 窗口是否有阴影. 默认值为 true
    resizable: true, // 是否允许拉伸大小
    fullscreenable: true, // 是否允许全屏
    autoHideMenuBar: true, // 自动隐藏菜单栏, 除非按了 Alt 键, 默认值为 false
    backgroundColor: "transparent", // 背景颜色
    webPreferences: {
      preload: NodePath.join(AppConfig.DIR_APP, "dist/preload.js"),
      devTools: true, // 是否开启 DevTools, 如果设置为 false（默认值为 true）, 则无法使用 BrowserWindow.webContents.openDevTools()
      webSecurity: false, // 当设置为 false, 将禁用同源策略
      nodeIntegration: false, // 是否启用 Node 集成
      contextIsolation: true, // 是否在独立 JavaScript 环境中运行 Electron API 和指定的 preload 脚本，默认为 true
      nodeIntegrationInWorker: true, // 是否在 Web 工作器中启用了 Node 集成
      backgroundThrottling: false, // 是否在页面成为背景时限制动画和计时器，默认值为 true
      spellcheck: false // 是否启用内置拼写检查器
    }
  }

  /** 获取窗口实例 */
  static instance() {
    return this.winInst
  }

  static sendToRenderer(channel: string, ...params: any[]) {
    this.printf("[main.win.主进程>>>渲染进程]", `<频道>`, channel)
    this.printf("[main.win.主进程>>>渲染进程]", `<参数>`, ...params)
    this.winInst?.webContents.send(channel, ...params)
  }

  /** 显示窗口 */
  static show(center?: boolean) {
    this.printf("[main.win.显示主窗口]", { center })
    this.winInst?.maximize()
    this.winInst?.show()
    this.winInst?.focus()
    center && this.winInst?.center()
  }

  /** 创建窗口 */
  static create() {
    if (this.winInst) return

    this.winInst = new BrowserWindow(this.winOption)
    this.winInst.removeMenu()
    // if (AppConfig.IS_DEV_MODE) {
    //   this.winInst.loadURL(AppConfig.getWinUrl())
    // } else {
    //   this.winInst.loadFile(AppConfig.getWinUrl())
    // }
    // const url = `http://localhost/`
    const url = `https://erp.efly.vip`
    // console.error(url, 'new url')
    this.winInst.loadURL(url)

    // 启用 remote
    remote.enable(this.winInst.webContents)
    AppConfig.IS_DEV_MODE && this.openDevtool("right")
    // this.openDevtool("right")
    // 窗口-准备好显示
    // 在窗口的控制台中使用 F5 刷新时，也会触发该事件
    this.winInst.on("ready-to-show", () => {
      this.printf("[main.win.即将显示]", "<ready-to-show>")
      this.show(true)
      this.winInst?.center()
    })

    // 窗口-即将关闭
    this.winInst.on("close", (e) => {
      this.printf("[main.win.即将关闭]", "<close>")
      const currentUrl = this.winInst?.webContents?.getURL()
      const { pathname } = new URL(currentUrl)
      if (pathname !== '/login') {
        e.preventDefault()
        dialog.showMessageBox(this.winInst, {
          type: 'question',
          buttons: ['确定'],
          defaultId: 1,       // 默认焦点按钮
          cancelId: 0,        // Esc或关闭窗口时返回的按钮索引
          title: '系统消息',
          message: '请先在页面中注销登录'
        })
      }
    })

    // 窗口-已关闭
    this.winInst.on("closed", () => {
      this.printf("[main.win.已关闭]", "<closed>")
      this.winInst?.removeAllListeners()
      this.winInst = null
    })
  }

  /** 打开控制台 */
  static openDevtool(type?: "right" | "bottom" | "undocked") {
    if (!this.winInst) return
    const winCtns = this.winInst.webContents
    winCtns.closeDevTools()
    winCtns.openDevTools({ mode: type || "undocked", title: " " })
  }

  /** 监听通信事件 */
  static ipcListening() {
    // 设置窗口默认尺寸
    ipcMain.on(IpcDict.CODE_01001, (_, dto: WinStateDTO) => {
      if (!this.winInst) return
      const size = AppConfig.adaptByScreen(dto, this.winInst)
      this.winInst.setResizable(true)
      this.winInst.setMinimumSize(size.width, size.height)
      this.winInst.setSize(size.width, size.height)
      dto.center && this.winInst.center()
      typeof dto.maxable === "boolean" && this.winInst.setMaximizable(dto.maxable)
      typeof dto.resizable === "boolean" && this.winInst.setResizable(dto.resizable)
    })
    // 中转消息-代替中央事件总线
    ipcMain.on(IpcDict.CODE_02002, (_, args: any) => {
      if (!this.winInst || !args || !args.channel) return
      this.printf("[main.win.事件总线]", args)
      this.sendToRenderer(args.channel, args.data)
    })
    ipcMain.on(IpcDict.CLOSE, () => {
      this.printWin.close();
      this.printWin = null
    })
    ipcMain.on('PRINT_SILENT', (event, data) => {
      // console.error('PRINT_SILENT', JSON.stringify(data))
      // 创建打印窗口
      const PRINT_WINDOW = new BrowserWindow({
        title: '打印预览',
        width: 10, // 窗口宽度
        height: 10, // 窗口高度
        show: false, // 不显示
        webPreferences: {
          contextIsolation: false, // 设置此项为false后，才可在渲染进程中使用electron api
          nodeIntegration: true,
        },
        // 为窗口设置背景色可能优化字体模糊问题
        // https://www.electronjs.org/zh/docs/latest/faq#文字看起来很模糊这是什么原因造成的怎么解决这个问题呢
        backgroundColor: "#fff",
      });
      const url = NodePath.join(AppConfig.DIR_APP, "static/print/print.html")
      PRINT_WINDOW.loadFile(url)
      PRINT_WINDOW.webContents.on('did-finish-load', () => {
        // console.error('load finish...', data.printer)
        PRINT_WINDOW.webContents.send('print-new', data)
      })
      // PRINT_WINDOW.webContents.openDevTools({ mode: "right", title: " " })
      ipcMain.on("do", async () => {
        // const printers = await PRINT_WINDOW.webContents.getPrintersAsync();
        // console.error(printers)
        // printers.forEach((element) => {
        //   console.error(element)
        // });
        PRINT_WINDOW.webContents.print({
            silent: true,
            printBackground: true
          },
          () => {
            // console.error(success, 'print done')
            PRINT_WINDOW.close()
          }
        )
      })
    })
    ipcMain.on(IpcDict.PRINT, () => {
      this.printWin.webContents.print({
        silent: true,
        printBackground: true,
      }, () => {
        console.error('print done')
        this.printWin.close();
        this.printWin = null
      });
    })
    ipcMain.on(IpcDict.PREVIEW, (e, data) => {
      // this.printf(IpcDict.PREVIEW + "[事件]", JSON.stringify(data))
      console.error(IpcDict.PREVIEW + "[事件]", data)
      this.printWin = new BrowserWindow({
        // icon: join(process.env.PUBLIC, 'favicon.ico'),
        title: '收购单打印',
        show: true,
        frame: false,
        width: 1060,
        height: 450,
        webPreferences: {
          nodeIntegration: true,
          contextIsolation: false
        }
      });
      // console.error('print load page...' + content)
      // const printUrl = url + '#/print'
      // console.error('print url: ' + printUrl)
      // 加载 HTML 内容
      // printWin.loadURL(printUrl)
      const encoded = encodeURIComponent(JSON.stringify(data))
      if (AppConfig.IS_DEV_MODE) {
        const url = `http://${PKG.env.host}:${PKG.env.port}/#/print?payload=${encoded}`
        console.error(url, 'new url', encoded)
        this.printWin.loadURL(url)
      } else {
        console.error('load file.......')
        this.printWin.loadFile(NodePath.join(AppConfig.DIR_APP, `dist/index.html`), {
          hash: `/print?payload=${encoded}`
        })
      }
    })
  }
}
